{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Sample PixieApp that provides Stock Ticker information"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import json\n",
    "from pandas_datareader import data\n",
    "from datetime import datetime, timedelta\n",
    "from pixiedust.display.app import *\n",
    "\n",
    "@PixieApp\n",
    "class StockViewer():\n",
    "    \"\"\"\n",
    "    Sample Stock Viewer PixieApp with live quotes\n",
    "    \"\"\"\n",
    "    \n",
    "    def setup(self):\n",
    "        self.tickers = {}\n",
    "        self.start = datetime(2014,1,1)\n",
    "        self.end = datetime.today()\n",
    "        self.show = \"table\"\n",
    "        self.measurements = [\"Open\", \"Close\", \"High\", \"Low\", \"Volume\"]\n",
    "        self.sel_measurement = self.measurements[0]\n",
    "        self.dateranges = [(30,\"1M\"), (90,\"3M\"), (180,\"6M\"), (365,\"1Y\"), (730,\"2Y\")]\n",
    "        self.sel_daterange = self.dateranges[0][0]\n",
    "        self.pixieapp_entity = None\n",
    "        self.provider = \"yahoo\"\n",
    "        self.providers = [\"google\", \"yahoo\", \"yahoo-actions\", \"yahoo-dividends\", \"enigma\", \"fred\", \n",
    "                          \"famafrench\", \"oecd\", \"eurostat\", \"edga-index\", \"nasdaq\", \"quandl\"]\n",
    "        \n",
    "    def enable_ticker(self, ticker, enable):\n",
    "        if ticker in self.tickers:\n",
    "            self.tickers[ticker][\"enable\"] = (enable == \"true\")\n",
    "            self.updatePDF()\n",
    "            \n",
    "    def update_measurement(self, measurement):\n",
    "        self.sel_measurement=measurement\n",
    "        self.updatePDF()\n",
    "        \n",
    "    def update_daterange(self, daterange):\n",
    "        self.sel_daterange=daterange\n",
    "        self.updatePDF()\n",
    "        \n",
    "    def update_provider(self, provider):\n",
    "        self.provider = provider\n",
    "        #rebuild all ticker dataframes\n",
    "        self.pixieapp_entity = None\n",
    "        for ticker in self.tickers:\n",
    "            self.add_ticker(ticker)\n",
    "            \n",
    "    def updatePDF(self):\n",
    "        df = pd.DataFrame({k: v['pdf'][self.sel_measurement] for k,v in self.tickers.items() if v['enable'] is True})\n",
    "        self.pixieapp_entity = df[(datetime.today()-timedelta(days=self.sel_daterange)):datetime.today()]\n",
    "        self.pixieapp_entity.reset_index(inplace=True)\n",
    "\n",
    "    def add_ticker(self, ticker):\n",
    "        try:\n",
    "            self.tickers[ticker] = {\n",
    "                \"pdf\" : data.DataReader(ticker,self.provider,self.start,self.end),\n",
    "                \"enable\": True,\n",
    "                \"exception\":None\n",
    "            }\n",
    "            self.updatePDF()\n",
    "            print(\"Successfully added {}.\".format(ticker))\n",
    "        except Exception as exc:\n",
    "            self.tickers[ticker][\"exception\"] = exc\n",
    "            print(\"Ticker not found. Please enter a valid ticker. {}\".format(exc))\n",
    "        \n",
    "    @route(tickersList=\"*\")\n",
    "    def tickers_list(self):\n",
    "        return \"\"\"\n",
    "        {%for ticker in this.tickers%}\n",
    "        <input type=\"checkbox\" checked id=\"{{ticker}}{{prefix}}\" \n",
    "            pd_script=\"self.enable_ticker('{{ticker}}', '$val({{ticker}}{{prefix}})')\"\n",
    "            pd_refresh=\"target{{prefix}}\">\n",
    "            {{ticker}}\n",
    "        {%endfor%}\n",
    "        \"\"\"\n",
    "    \n",
    "    def get_pd_options(self):\n",
    "        ret_value = {\n",
    "            \"noChartCache\": \"true\"\n",
    "        }\n",
    "        if self.show == \"table\":\n",
    "            ret_value.update({\n",
    "                \"handlerId\":\"dataframe\" \n",
    "            })\n",
    "        else:\n",
    "            ret_value.update({\n",
    "                \"handlerId\": \"lineChart\",\n",
    "                \"keyFields\": \"Date\",\n",
    "                \"aggregation\": \"SUM\",\n",
    "                \"rowCount\":\"1000\",\n",
    "                \"timeseries\":\"true\",\n",
    "                \"valueFields\":\",\".join(list(self.tickers.keys()))\n",
    "            })\n",
    "        return json.dumps(ret_value)\n",
    "    \n",
    "    @route(tickersContent=\"*\")\n",
    "    def tickers_content(self):\n",
    "        if self.pixieapp_entity is None:\n",
    "            return \"<div/>\"\n",
    "    \n",
    "        return \"\"\"\n",
    "<div pd_entity pd_render_onload>\n",
    "    <pd_options>\n",
    "        {{this.get_pd_options()}}\n",
    "    </pd_options>\n",
    "</div>\n",
    "        \"\"\"\n",
    "\n",
    "    @route()\n",
    "    def default(self):         \n",
    "        return \"\"\"\n",
    "<div class=\"row\">\n",
    "    <center>\n",
    "    <label>Provider:</label>\n",
    "    <select id=\"provider{{prefix}}\" pd_script=\"self.update_provider('$val(provider{{prefix}})')\" pd_refresh=\"target{{prefix}}\">\n",
    "        {%for provider in this.providers %}\n",
    "            <option {%if provider==this.provider%}selected{%endif%} value=\"{{provider}}\">{{provider}}</option>\n",
    "        {%endfor%}\n",
    "    </select>\n",
    "    </center>\n",
    "</div>\n",
    "<div class=\"row\">\n",
    "    <div class=\"form-group col-sm-2\" style=\"padding-right:10px;\">\n",
    "        <p>\n",
    "        <label>1. Add tickers</label>\n",
    "        </p>\n",
    "        \n",
    "        <p>\n",
    "        <input id=\"t\" name=\"tickerInput\">\n",
    "        </p>\n",
    "        \n",
    "        <p>\n",
    "        <button type=\"submit\" id=\"check\" pd_script=\"self.add_ticker('$val(t)')\" pd_refresh=\"tickersList{{prefix}},target{{prefix}}\">\n",
    "            Add \n",
    "        </button>\n",
    "        </p>\n",
    "        \n",
    "        <p>\n",
    "        <label>2. Select measurement, date range</label>\n",
    "        </p>\n",
    "        \n",
    "        <p>\n",
    "        <select id=\"measurement{{prefix}}\" pd_model=\"measurement\"\n",
    "            pd_script=\"self.update_measurement('$val(measurement{{prefix}})')\" pd_refresh=\"target{{prefix}}\">\n",
    "            {%for measurement in this.measurements %}\n",
    "                <option value=\"{{measurement}}\">{{measurement}}</option>\n",
    "            {%endfor%}\n",
    "        </select>\n",
    "        </p>\n",
    "        \n",
    "        <p>\n",
    "        <select id=\"dateRange{{prefix}}\"\n",
    "            pd_script=\"self.update_daterange($val(dateRange{{prefix}}))\" pd_refresh=\"target{{prefix}}\">\n",
    "            {%for daterange in this.dateranges %}\n",
    "                <option value=\"{{daterange[0]}}\">{{daterange[1]}}</option>\n",
    "            {%endfor%}\n",
    "        </select>\n",
    "        </p>\n",
    "        \n",
    "        <p>\n",
    "        <label>3. Visualize</label>\n",
    "        </p>        \n",
    "        \n",
    "        <p>\n",
    "        <button type=\"submit\" class=\"btn btn-primary\" pd_refresh=\"target{{prefix}}\" pd_script=\"self.show='table'\">\n",
    "            Preview as nice table\n",
    "        </button>\n",
    "        </p>\n",
    "        \n",
    "        <p>\n",
    "        <button type=\"submit\" class=\"btn btn-primary\" pd_refresh=\"target{{prefix}}\" pd_script=\"self.show='line'\">\n",
    "            Line chart\n",
    "        </button>\n",
    "        </p>\n",
    "        \n",
    "    </div>\n",
    "    \n",
    "    <div class=\"form-group col-sm-4 no_loading_msg\" id=\"tickersList{{prefix}}\" pd_render_onload pd_options=\"tickersList=true\">\n",
    "    </div>\n",
    "    \n",
    "    <div class=\"form-group col-sm-10\" id=\"target{{prefix}}\" pd_render_onload pd_options=\"tickersContent=true\">\n",
    "    </div>\n",
    "</div>\n",
    "\"\"\"\n",
    "\n",
    "a = StockViewer()\n",
    "a.run(runInDialog='false')"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "celltoolbar": "Edit Metadata",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "test"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
